home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / QDDVX102.ZIP / contrib / dvx / qdeck / kern / scale.c < prev   
Text File  |  1993-07-15  |  8KB  |  240 lines

  1. /*----------------------------------------------------------------------*/
  2. /*                                    */
  3. /*  Sample usage of scalable font fractional spacing and kerning.    */
  4. /*                                    */
  5. /*  This file demonstrates how scalable fonts can be used in the    */
  6. /*  DESQview/X environment.  It emphasises how fractional spacing    */
  7. /*  and kerning are performed.                        */
  8. /*                                    */
  9. /*----------------------------------------------------------------------*/
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <X11/Xmd.h>
  14. #include <X11/X.h>
  15. #include <X11/Xos.h>
  16. #include <X11/Xlib.h>
  17. #include <X11/Xutil.h>
  18. #include <X11/Xatom.h>
  19.  
  20.  
  21.  
  22. typedef struct KERNPAIRtag
  23. {
  24.   char chLeft;
  25.   char chRight;
  26.   INT32 xKernOffset;
  27. } KERNPAIR;
  28.  
  29.  
  30. Display          *dpy;
  31. int                  screen;
  32. Window             root;
  33. GC             gcBase;
  34. Window             winMain;
  35. KERNPAIR         *pKernBase;
  36. XFontStruct         *xfn;
  37.  
  38.  
  39. /*----------------------------------------------------------------------*/
  40. /*        BASIC X OPERATIONS                    */
  41. /*----------------------------------------------------------------------*/
  42.  
  43. main ()
  44. {
  45. XSetWindowAttributes xswa;
  46.  
  47.   dpy            = XOpenDisplay (NULL);
  48.   screen        = DefaultScreen(dpy);
  49.   root            = RootWindow(dpy,screen);
  50.   gcBase        = DefaultGC(dpy,screen);
  51.   winMain        = XCreateSimpleWindow (dpy, root, 0, 0, 500, 100, 0, 0L, 15L);
  52.   xswa.event_mask    = ExposureMask;
  53.   XChangeWindowAttributes (dpy, winMain, CWEventMask, &xswa);
  54.   XMapWindow (dpy, winMain);
  55.   InitText ("Times Roman-Medium-R", 24);
  56.  
  57.   while (1)
  58.   {
  59.   XEvent xe;
  60.  
  61.     XNextEvent (dpy,&xe);
  62.     switch (xe.type)
  63.     {
  64.       case Expose:
  65.     DrawText (10, 50, "This is the string to be printed.");
  66.     break;
  67.  
  68.       case DestroyNotify:
  69.     ClearText ();
  70.     break;
  71.     }
  72.   }
  73. }
  74.  
  75.  
  76. /*----------------------------------------------------------------------*/
  77. /*    SAMPLE CODE FOR FRACTIONAL SPACING AND KERNING            */
  78. /*----------------------------------------------------------------------*/
  79.  
  80.  
  81. /*----------------------------------------------------------------------*/
  82. /*    LOAD FONT AND READ KERNING PAIRS                */
  83. /*----------------------------------------------------------------------*/
  84.  
  85. InitText (char *pszFont, int PointSize)
  86. {
  87. char szName[256];
  88. int xRes;
  89. int yRes;
  90. Atom atomKernLabel, atomKernVar;
  91. XGCValues values;
  92. KERNPAIR *pKern;
  93. Atom atomType;
  94. int iFormat;
  95. long cItems;
  96. long bytes_after;
  97. char *pProp;
  98. char *pPropBase;
  99. int  cProps;
  100.  
  101.   xRes = 75;
  102.   yRes = 75;
  103.   sprintf (szName, "-Adobe-%s-Normal--*-%d-%d-%d-*-*-*-Adobe",
  104.         pszFont, PointSize*10, xRes, yRes);
  105.  
  106.   xfn = XLoadQueryFont (dpy, szName);               /* load the font     */
  107.   if (!xfn)
  108.   {
  109.     printf("Could not load font \"%s\".\n",szName);
  110.     exit(1);
  111.   }
  112.   else
  113.   {
  114.     values.font = xfn->fid;
  115.     XChangeGC (dpy, gcBase, GCFont, &values);
  116.  
  117.     /* Now we want to grab the kerning pairs.  This is done by looking at the */
  118.     /* font property 'KERNING_PAIRS' to find the root windows property name.  */
  119.     /* The root property is next examined to extract the needed pairs.    The   */
  120.     /* pairs are transferred into an array.                      */
  121.  
  122.     atomKernLabel = XInternAtom (dpy, "KERNING_PAIRS", 0);/* enumerate prop */
  123.     XGetFontProperty (xfn, atomKernLabel, &atomKernVar);  /* grab root name */
  124.     XGetWindowProperty (dpy, root, atomKernVar, 0, 8192,  /* get the info   */
  125.         False, AnyPropertyType, &atomType, &iFormat, &cItems, &bytes_after, &pProp);
  126.     pPropBase = pProp;
  127.     cProps = *(INT16 *)pProp;     pProp+=2;    /* get number of properties */
  128.     pKern = (KERNPAIR *)malloc (sizeof(KERNPAIR) * (cProps+1));
  129.     pKernBase = pKern;
  130.     while (cProps--)
  131.     {
  132.       pKern->chLeft     = *pProp++;          /* left character in pair */
  133.       pKern->chRight     = *pProp++;         /* right character in pair */
  134.       pKern->xKernOffset = (INT32)(*(INT16 *)pProp) + ((INT32)(*(INT16 *)(pProp+2)))*65536L;
  135.       pProp += 4;
  136.       pKern++;
  137.     }
  138.     pKern->chLeft      = 0;                   /* mark end of table */
  139.     pKern->chRight     = 0;
  140.     pKern->xKernOffset = 0;
  141.  
  142.     XFree (pPropBase);                   /* we are done with the data */
  143.   }
  144. }
  145.  
  146.  
  147. /*----------------------------------------------------------------------*/
  148. /*    UNLOAD FONT AND KERNING PAIRS                    */
  149. /*----------------------------------------------------------------------*/
  150.  
  151. ClearText ()
  152. {
  153.   free (pKernBase);                      /* free kerning stuff */
  154.   XFreeFont (dpy, xfn);                  /* get rid of font */
  155. }
  156.  
  157. /*----------------------------------------------------------------------*/
  158. /*    FIND PAIR OF CHARACTERS IN KERNING ARRAY            */
  159. /*----------------------------------------------------------------------*/
  160.  
  161. /* This routine just does a simple sequential search to find the kerning */
  162. /* pair.  A better implementation would be to sort the array and perform */
  163. /* binary searches.                             */
  164.  
  165. INT32 LookupKern (char chLeft, char chRight)
  166. {
  167. KERNPAIR *pKern;
  168.  
  169.   pKern = pKernBase;
  170.   while (pKern->chLeft)
  171.   {
  172.     if ((pKern->chLeft == chLeft) && (pKern->chRight == chRight))
  173.       return (pKern->xKernOffset);                /* return delta */
  174.     pKern++;
  175.   }
  176.   return (0L);                        /* no pair -> delta = 0 */
  177. }
  178.  
  179. /*----------------------------------------------------------------------*/
  180. /*    OUTPUT ONE LINE OF TEXT WITH KERNING + FRACTIONAL SPACING    */
  181. /*----------------------------------------------------------------------*/
  182.  
  183. /* This routine performs fractional spacing and kering as described    */
  184. /* in the documentation.  A series of XTextItem text chunks is output    */
  185. /* with delta "corrections" to compensate for the difference between    */
  186. /* rouded integer spacing and fractional spacing.            */
  187.  
  188. DrawText (int xPos, int yPos, char *pszText)
  189. {
  190. char chPrev;            /* previous character                */
  191. XTextItem ati[100];        /* XTextItem array for cummulation        */
  192. int cItems;            /* count of XTextItem entries            */
  193. INT16 xPosRound;        /* running x position as rounded integer    */
  194. INT32 xPosFixed;        /* running x position as 16.16 fixed nota'n */
  195. char *pszBase;            /* running pointer to base of text chunk    */
  196. INT16 DeltaInt;         /* rounded integer character width        */
  197. INT16 DeltaFrac;        /* signed fractional part of character wid. */
  198. INT16 xPosCheck;        /* variable fo comparing widths         */
  199. int  cChars;            /* number of charcters in XTextItem entry   */
  200.  
  201.   cChars    = 0;        /* initialize some stuff            */
  202.   chPrev    = 0;
  203.   xPosRound = 0;
  204.   xPosFixed = 0;
  205.   cItems    = 0;
  206.   pszBase   = pszText;
  207.   ati[0].delta    = 0;
  208.  
  209.   while (*pszText)
  210.   {
  211.     xPosFixed += LookupKern (chPrev, *pszText);  /* make kerning adjustment */
  212.     xPosCheck  = (INT16)((xPosFixed+32768L)>>16);      /* get round (16.16) */
  213.     if (xPosCheck != xPosRound)           /* is "correction" necessary? */
  214.     {
  215.       ati[cItems].chars   = pszBase;    /* sequence of characters to output */
  216.       ati[cItems].nchars  = cChars;      /* number of characters to output */
  217.       ati[cItems+1].delta = xPosCheck - xPosRound; /* how much of an adjmnt */
  218.       ati[cItems].font      = 0;         /* we want to use the current font */
  219.       xPosRound = xPosCheck;         /* "correct" the running rounded x pos */
  220.       pszBase    = pszText;         /* next text chunk will start here */
  221.       cChars    = 0;                  /* reset count for next chunk */
  222.       cItems++;                  /* increment XTextItem counter */
  223.     }
  224.     DeltaInt   = xfn->per_char[(INT16)*pszText - xfn->min_char_or_byte2].width;
  225.     DeltaFrac  = xfn->per_char[(INT16)*pszText - xfn->min_char_or_byte2].attributes;
  226.     xPosRound += DeltaInt;               /* update running x counters */
  227.     xPosFixed += (((INT32)DeltaInt)<<16) + (INT32)DeltaFrac;
  228.     cChars++;                 /* note that (INT32)DeltaFrac is signed */
  229.     chPrev = *pszText++;    /* so that it can both lower and raise DeltaInt */
  230.   }
  231.   ati[cItems].chars  = pszBase;            /* final XTextItem chunk */
  232.   ati[cItems].nchars = cChars;
  233.   ati[cItems].font   = 0;
  234.   cItems++;
  235.  
  236.   /* now, we actually print out the results of the above calculations    */
  237.  
  238.   XDrawText   (dpy, winMain, gcBase, xPos, yPos, ati, cItems);
  239. }
  240.